#pragma once

#include <sstream>
#include <unordered_map>
#include "Util.hpp"

/*
	备份信息的描述和组织
*/

namespace cloud
{
	class DataManager
	{
	private:
		std::unordered_map<std::string, std::string> _table;//格式:key:文件名 value:文件名-大小-最后一次修改时间
		std::string _backup_file;
	public:
		DataManager(std::string backup_file)
			:_backup_file(backup_file)
		{
			InitLoad();//初始化
		}
		bool Insert(const std::string& key,const std::string& val)//插入
		{
			_table[key] = val;
			storage();
			return true;
		}
		bool Update(const std::string& key, const std::string& val)//更新
		{
			_table[key] = val;
			storage();
			return true;
		}
		bool storage()//更新配置文件
		{
			std::stringstream ss;
			auto it = _table.begin();
			while (it != _table.end())
			{
				ss << it->first << " " << it->second << "\n";//数据格式
				++it;
			}
			FileUtil file(_backup_file);
			file.SetContent(ss.str());//更新
			return true;
		}
		bool GetOneByKey(const std::string& key,std::string* val)//通过key进行查找,返回value
		{
			auto it = _table.find(key);
			if (it == _table.end())
			{
				return false;
			}
			*val = it->second;
			return true;
		}
	private:
		int split(std::vector<std::string>& _array,const std::string& sep,std::string& body)//将body按照分隔符pos去切割,存到_array
		{
			int count = 0;
			size_t pos = 0, idx = 0;
			while (1)
			{
				pos = body.find(sep, idx);//从idx开始查找sep
				if (pos == std::string::npos)//查找不到
				{
					break;
				}
				if (pos == idx)//从idx开始查找,在idx找到,证明该位置就是sep,需要进行特殊处理,不然会死循环
				{
					pos += sep.size();
					continue;
				}
				std::string str = body.substr(idx,pos - idx);//左闭右开,pos - idx切割个数刚刚好
				_array.push_back(str);
				++count;//已经切割的个数
				idx = pos + sep.size();
			}
			if (idx < body.size())//最后一个没有找到空格,也要进行插入 文件名 文件名-大小-最后一次修改时间\n
			{				      //即文件名-大小-最后一次修改时间
				_array.push_back(body.substr(idx,body.size() - idx));
				++count;
			}
			return count;
		}
		bool InitLoad()
		{
			FileUtil file(_backup_file);//获取备份文件信息
			std::string body;
			file.GetContent(&body);//文件名 文件名-大小-最后一次修改时间\n文件名 文件名-大小-最后一次修改时间\n文件名 文件名-大小-最后一次修改时间\n 
			std::vector<std::string> _array;
			split(_array,"\n", body);//数组某个元素存的是 文件名 文件名-大小-最后一次修改时间\n
			for (auto str : _array)
			{
				std::vector<std::string> tmp;
				split(tmp," ",str);
				if (tmp.size() != 2)
				{
					continue;
				}
				_table[tmp[0]] = tmp[1];//key:文件名 value:最后一次修改时间
			}
			return true;
		}
	};
}

